package routes

import (
	"github.com/gofiber/fiber/v2"
	"reflect"
	"strings"
)

// RegisterResourceRoutes 用于设置资源路由
func RegisterResourceRoutes(router fiber.Router, prefix string, controller interface{}) {
	controllerValue := reflect.ValueOf(controller)
	controllerType := controllerValue.Type()

	if controllerType.Kind() != reflect.Ptr || controllerType.Elem().Kind() != reflect.Struct {
		panic("controller must be a pointer to a struct")
	}

	resourceRoutes := router.Group(prefix)
	// 定义资源路由映射
	resourceMap := map[string]string{
		"Index":   "GET /",
		"Show":    "GET /:id",
		"Store":   "POST /",
		"Update":  "PUT /:id",
		"Destroy": "DELETE /:id",
	}

	for method, route := range resourceMap {
		if methodFunc := controllerValue.MethodByName(method); methodFunc.IsValid() {
			routeParts := strings.Split(route, " ")
			httpMethod := routeParts[0]
			routePath := routeParts[1]

			switch httpMethod {
			case "GET":
				resourceRoutes.Get(routePath, wrapHandler(controllerValue, method))
			case "POST":
				resourceRoutes.Post(routePath, wrapHandler(controllerValue, method))
			case "PUT":
				resourceRoutes.Put(routePath, wrapHandler(controllerValue, method))
			case "DELETE":
				resourceRoutes.Delete(routePath, wrapHandler(controllerValue, method))
			}
		}
	}
}

// wrapHandler 用于包装控制器方法以适应 Fiber 的处理函数
func wrapHandler(controllerValue reflect.Value, methodName string) fiber.Handler {
	return func(c *fiber.Ctx) error {
		results := controllerValue.MethodByName(methodName).Call([]reflect.Value{reflect.ValueOf(c)})
		if len(results) == 0 {
			return nil
		}
		if err, ok := results[0].Interface().(error); ok {
			return err
		}
		return nil
	}
}
